package main

import "fmt"

// 切片  相当于可变长度的数组

func main() {
	// 切片的定义
	var s1 []int //定义一个存放int类型元素的切片
	var s2 []string
	fmt.Println(s1, s2)
	fmt.Println(s1 == nil) // nil相当于null的意思
	fmt.Println(s2 == nil)

	// 初始化
	var s0 = make([]int, 4, 6)
	s1 = []int{1, 2, 3}
	s2 = []string{"x", "y", "z"}
	fmt.Println(s0,s1, s2)

	// 长度和容量
	fmt.Printf("len(s1): %d, cap(s1): %d\n", len(s1), cap(s1))
	fmt.Printf("len(s2): %d, cap(s2): %d\n", len(s2), cap(s2))

	// 2. 由数组得到切片
	a1 := [...]int{1, 3, 5, 7, 9}
	s3 := a1[0:3] // 左闭右开
	fmt.Println(s3)

	// 其他几种切片的方式
	s4 := a1[:3]  // ==> [1, 3, 5]
	s5 := a1[3:4] //  ==> [7]
	s6 := a1[:]   //  ==> [1, 3, 5, 7, 9]

	// 切片的容量 是指从切片的第一个元素到底层数组的最后一个元素的个数数量，只能向后拓展
	fmt.Printf("len(s4): %d, cap(s4): %d\n", len(s4), cap(s4))
	fmt.Printf("len(s5): %d, cap(s5): %d\n", len(s5), cap(s5))
	fmt.Printf("len(s5): %d, cap(s5): %d\n", len(s6), cap(s6))

	// 切片再切片  注意容量是指底层数组的元素位置
	s7 := s4[2:]
	fmt.Printf("len(s7): %d, cap(s7): %d\n", len(s7), cap(s7))

	// 切片是一个引用类型 其都指向它的底层数组
	fmt.Println(s4)
	a1[1] = 11
	fmt.Println(s4)

	// append() 为切片追加元素
	s8 := []string{"北京", "上海", "广州"}
	fmt.Println(s1)
	fmt.Printf("len(s1):%d, cap(s1):%d\n", len(s8), cap(s8))

	// 调用append函数必须用原来的切片变量接收返回值
	// append追加元素时，原来的底层数组放不下的时候，Go底层就会换一个新的底层数组，为了防止原来的切片丢失，需要用原来的切片来进行接收
	s8 = append(s8, "成都")
	fmt.Println(s8)
	fmt.Printf("len(s8):%d, cap(s8):%d\n", len(s8), cap(s8))

	// append追加多个元素
	s9 := []string{"大连", "重庆", "西安"}
	s8 = append(s8, s9...) //...表示拆开
	fmt.Println(s8)
	fmt.Printf("len(s8):%d, cap(s8):%d\n", len(s8), cap(s8))


	a0 := []int{1, 3, 5}
	a2 := a0
	a3 := make([]int, 3)

	// 拷贝赋值  值拷贝
	copy(a3, a0)
	fmt.Println(a0, a2, a3)
	a0[0] = 100
	fmt.Println(a0, a2, a3)

	// 从切片中删除元素2
	a := []int{1, 2, 3, 4, 5, 6}
	a = append(a[:1], a[2:]...)
	fmt.Println(a)

	x1 := [...]int{1, 3, 5, 7}
	s11 := x1[:]
	fmt.Println(s11, len(s11), cap(s11))
	// 1. 切片不保存具体的值
	// 2. 切片对应一个底层数组
	// 3. 底层数组都是占用一块连续的内存空间
	s11 = append(s11[:1], s11[2:]...) // 修改了底层数组！！ 前移元素覆盖掉原来的数组
	fmt.Println(s11, len(s11), cap(s11))
	// 问： x1数组元素是多少
	fmt.Println(x1, len(x1), cap(x1)) // ==> [1, 5, 7, 7]
}

